/***************************************************************************
 *   Copyright (C) 2007 by les pandas rouges   *
 *   pouet@pouet   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "shaperecdisplaymanager.h"
#include <QRectF>
#include <QLineF>
#include <QMessageBox>

ShapeRecDisplayManager::ShapeRecDisplayManager():scale(1), screen(NULL), nbPoints(0), points(NULL), pathLines(NULL), hlPoint(NULL)
{
    connect(&this->slid, SIGNAL(valueChanged(int)), this, SLOT(changeScale(int)));
    this->scene.setBackgroundBrush(Qt::gray);
    this->screen = this->scene.addRect(QRectF(0,0,256,192), QPen(Qt::white), QBrush(Qt::white));
    this->screen->setZValue(SCREENZ);
    this->view.setScene(&this->scene);
    this->view.setAlignment(Qt::AlignLeft | Qt::AlignTop);
    this->view.setRenderHints(QPainter::Antialiasing);
    this->slid.setMinimum(1);
    this->slid.setMaximum(20);
    this->slid.setValue(1);
    this->slid.setOrientation(Qt::Horizontal);
    this->slid.setTickPosition(QSlider::TicksAbove);
    this->slid.setTickInterval(1);
}


ShapeRecDisplayManager::~ShapeRecDisplayManager()
{
    this->eraseAll();
    this->scene.removeItem(this->screen);
    if(this->hlPoint != NULL)
    {
        this->scene.removeItem(this->hlPoint);
    }
    delete this->screen;
}

void ShapeRecDisplayManager::setActivePoint(int ind)
{
    
    if(this->points != NULL)
    {
	if(this->hlPoint != NULL)
	{
		this->hlPoint->setPos(this->points[ind]->rect().x()+0.25, this->points[ind]->rect().y()+0.25);
	}else{
		this->hlPoint = this->scene.addEllipse(QRectF(this->points[ind]->x() - 2, this->points[ind]->y() - 2, 4, 4), QPen(Qt::cyan), QBrush(Qt::cyan));
        }
    }
}

void ShapeRecDisplayManager::drawPath(MyIntPoint* points, quint16 _nbPoints)
{
    this->nbPoints = _nbPoints;
    this->points = new QGraphicsEllipseItem*[_nbPoints];

    if (nbPoints>0)
    {
        this->pathLines = new QGraphicsLineItem*[nbPoints-1];
    }
    this->points[0] = this->drawCircle(points[0]);
    this->points[0]->setZValue((qreal) POINTZ);
    for (int i=1; i<_nbPoints; i++)
    {
        this->points[i] = this->drawCircle(points[i]);
        this->points[i]->setZValue((qreal) POINTZ);
        this->pathLines[i-1] = this->drawLine(points[i-1], points[i]);
        this->pathLines[i-1]->setZValue((qreal) PATHLINEZ);
    }
}
//const QPen& pen, const QBrush& brush)
void ShapeRecDisplayManager::drawAdditionalCircle(const MyIntPoint& center, unsigned short radius, MyColors penColor, MyColors brushColor)
{
    QGraphicsItem* item = this->drawCircle(center, radius, QPen(convColor(penColor)), QBrush(convColor(brushColor)));
    item->setZValue((qreal) ADDITIONALZ);
    this->additionalDisplay.append(item);
}

void ShapeRecDisplayManager::drawAdditionalRectangle(const MyIntPoint& topLeft, unsigned short width, unsigned short height, MyColors penColor, MyColors brushColor)
{
    QGraphicsItem* item = this->drawRectangle(topLeft, width, height, QPen(convColor(penColor)), QBrush(convColor(brushColor)));
    item->setZValue((qreal) ADDITIONALZ);
    this->additionalDisplay.append(item);
}

void ShapeRecDisplayManager::drawAdditionalLine(const MyIntPoint& p1, const MyIntPoint& p2, MyColors penColor)
{
    QGraphicsItem* item = this->drawLine(p1, p2, QPen(convColor(penColor)));
    item->setZValue((qreal) ADDITIONALZ);
    this->additionalDisplay.append(item);
}

void ShapeRecDisplayManager::drawContextCircle(const MyIntPoint& center, unsigned short radius, MyColors penColor, MyColors brushColor)
{
    QGraphicsItem* item = this->drawCircle(center, radius, QPen(convColor(penColor)), QBrush(convColor(brushColor)));
    item->setZValue((qreal) CONTEXTZ);
    this->contextDisplay.append(item);
}

void ShapeRecDisplayManager::drawContextRectangle(const MyIntPoint& topLeft, unsigned short width, unsigned short height, MyColors penColor, MyColors brushColor)
{
    QGraphicsItem* item = this->drawRectangle(topLeft, width, height, QPen(convColor(penColor)), QBrush(convColor(brushColor)));
    item->setZValue((qreal) CONTEXTZ);
    this->contextDisplay.append(item);
}

void ShapeRecDisplayManager::drawContextLine(const MyIntPoint& p1, const MyIntPoint& p2, MyColors penColor)
{
    QGraphicsItem* item = this->drawLine(p1, p2, QPen(convColor(penColor)));
    item->setZValue((qreal) CONTEXTZ);
    this->contextDisplay.append(item);
}


QGraphicsLineItem* ShapeRecDisplayManager::drawLine(const MyIntPoint& p1, const MyIntPoint& p2, const QPen& pen)
{
    return this->scene.addLine(QLineF((qreal)p1.x(), (qreal)p1.y(), (qreal)p2.x(), (qreal)p2.y()), pen);
}

QGraphicsEllipseItem* ShapeRecDisplayManager::drawCircle(const MyIntPoint& p, qreal radius, const QPen& pen, const QBrush& brush)
{
    return this->scene.addEllipse(QRectF((qreal)p.x() - radius/2, (qreal)p.y() - radius/2, (qreal)radius, (qreal)radius), pen, brush);
}

QGraphicsRectItem* ShapeRecDisplayManager::drawRectangle(const MyIntPoint& topLeft, quint16 width, quint16 height, const QPen& pen,const QBrush& brush)
{
    return this->scene.addRect(QRectF((qreal)topLeft.x(), (qreal)topLeft.y(), (qreal) width, (qreal)height), pen, brush);
}

void ShapeRecDisplayManager::changeScale(int value)
{
	int oldScale = this->scale;
	this->scale = value;
	qreal ratio = (qreal)value/(qreal)oldScale;
	this->view.scale(ratio, ratio);
}

void ShapeRecDisplayManager::eraseBase()
{
	for(int i=0; i<this->nbPoints; i++)
	{
		this->scene.removeItem(this->points[i]);
	}
	delete[] this->points;
	for(int i=0; i<this->nbPoints-1; i++)
	{
		this->scene.removeItem(this->pathLines[i]);
	}
	delete[] this->pathLines;
}

void ShapeRecDisplayManager::eraseAdditional()
{
	for(int i=0; i<this->additionalDisplay.size(); i++)
	{
		this->scene.removeItem(this->additionalDisplay[i]);
		delete this->additionalDisplay[i];
	}
	this->additionalDisplay.clear();
}

void ShapeRecDisplayManager::eraseContext()
{
	for(int i=0; i<this->contextDisplay.size(); i++)
	{
		this->scene.removeItem(this->contextDisplay[i]);
		delete this->contextDisplay[i];
	}
	this->contextDisplay.clear();
}

void ShapeRecDisplayManager::eraseAll()
{
	this->eraseContext();
	this->eraseAdditional();
	this->eraseBase();
}

QColor ShapeRecDisplayManager::convColor(MyColors c)
{
    switch (c)
    {
    case(WHITE) :
                    return Qt::white;
    case(BLACK) :
                    return Qt::black;
    case(RED) :
                    return Qt::red;
    case(DARKRED) :
                    return Qt::darkRed;
    case(GREEN) :
                    return Qt::green;
    case(DARKGREEN) :
                    return Qt::darkGreen;
    case(BLUE) :
                    return Qt::blue;
    case(DARKBLUE) :
                    return Qt::darkBlue;
    case(CYAN) :
                    return Qt::cyan;
    case(DARKCYAN) :
                    return Qt::darkCyan;
    case(MAGENTA) :
                    return Qt::magenta;
    case(DARKMAGENTA) :
                    return Qt::darkMagenta;
    case(YELLOW) :
                    return Qt::yellow;
    case(DARKYELLOW) :
                    return Qt::darkYellow;
    case(GRAY) :
                    return Qt::gray;
    case(DARKGRAY) :
                    return Qt::darkGray;
    case(LIGHTGRAY) :
                    return Qt::lightGray;
    case(TRANSPARENT) :
                    return Qt::transparent;
    default :
        return Qt::black;
    }
}
